#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define SERVER_PORT 9888
#define MAX_BUFFER_SIZE 1024
int serverForInfo;
char session_header[20];
void handle(int client_sock, char buffer[], int server_sock)
{
    char *method, *url, *DianTP_version, *cseq_header;
    char response[MAX_BUFFER_SIZE] = {0};
    char request[MAX_BUFFER_SIZE] = {0};

    method = strtok(buffer, " ");
    url = strtok(NULL, " ");
    DianTP_version = strtok(NULL, "\r\n");
    cseq_header = strtok(NULL, "\r\n");
    if (strcmp(method, "OPTIONS") == 0)
    {
        sprintf(response, "DianTP/0.5 200 OK\r\nCSeq: 1\r\nPublic methods: OPTIONS, SETUP, PLAY, TEARDOWN\r\n\r\n");
        printf("The information send to the client:\n%s", response);
        send(client_sock, response, strlen(response), 0);
    }
    else if (strcmp(method, "SETUP") == 0)
    {
        char *clientInfo = strtok(NULL, "\r\n");
        int session_id = rand() % 20000 + 1;
        struct sockaddr_in serverForInfo_Addr;
        socklen_t serverForInfo_Addr_len = sizeof(serverForInfo_Addr);
        serverForInfo = accept(server_sock, (struct sockaddr *)&serverForInfo_Addr, &serverForInfo_Addr_len);
        sprintf(response, "DianTP/0.5 200 OK\r\nCSeq: 2\r\n%s\r\nSession: %d\r\n\r\n", clientInfo, session_id);
        printf("The information send to the client:\n%s", response);
        send(client_sock, response, strlen(response), 0);
    }
    else if (strcmp(method, "PLAY") == 0)
    {
        char newResponse[MAX_BUFFER_SIZE] = {0};
        strcpy(session_header, strtok(NULL, "\r\n"));
        char *range = strtok(NULL, "\r\n");
        printf("The client's range is %s\n", range);
        sprintf(newResponse, "DianTP/0.5 200 OK\r\n%s\r\n%s\r\n\r\n", cseq_header, session_header);
        printf("The information send to the client:\n%s", response);
        printf("%s", newResponse);
        send(client_sock, newResponse, strlen(newResponse), 0);
        sleep(1);
        char sendinfo[MAX_BUFFER_SIZE] = "You are my cup of tea, my sweet potato pie.\n";
        send(serverForInfo, sendinfo, strlen(sendinfo), 0);
        sleep(1);
    }
    else if (strcmp(method, "TEARDOWN") == 0)
    {
        char *client_give_session_header = strtok(NULL, "\r\n");
        // printf("%s, %s", client_give_session_header, session_header);
        if (strcmp(client_give_session_header, session_header) == 0)
        {
            close(serverForInfo);
            printf("close %s's socket successfully\n\n", session_header);
        }
        else
        {
            send(serverForInfo, "DianTP/0.5 400 Bad Request\r\nCSeq: 4\r\n\r\n", MAX_BUFFER_SIZE, 0);
        }
    }
    else
    {
        char response[MAX_BUFFER_SIZE] = {0};
        sprintf(response, "DianTP/0.5 400 Bad Request\r\nCSeq: 1\r\n\r\n");
        send(client_sock, response, strlen(response), 0);
        printf("Unsupported DianTP request\n");
    }
    memset(buffer, 0, MAX_BUFFER_SIZE);
    printf("DianTP request received and handled successfully\n");
}

// 

int main()
{
    // 创建服务器socket
    srand(time(NULL));
    int server_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sock < 0)
    {
        printf("Failed to create socket");
        return -1;
    }

    // 绑定端口号
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    int bind_result = bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (bind_result < 0)
    {
        printf("Failed to bind port");
        return -1;
    }

    // 监听端口
    int listen_result = listen(server_sock, 5);
    if (listen_result < 0)
    {
        printf("Failed to listen port");
        return -1;
    }

    // 接收客户端请求
    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    int client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_addr_len);
    if (client_sock < 0)
    {
        printf("Failed to accept client connection");
        return -1;
    }

    // 接收客户端请求数据
    char buffer[MAX_BUFFER_SIZE];
    while (1)
    {
        int recv_size = recv(client_sock, buffer, MAX_BUFFER_SIZE, 0);
        if (recv_size <= 0)
        {
            printf("Failed to receive data");
            return -1;
        }
        handle(client_sock, buffer, server_sock);

    }
    // 关闭连接
    close(client_sock);
    close(server_sock);
    return 0;
}
